// LemCoop
// Copyright (C) 2013  Oliver Naumann <bldrax@gmail.com>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

/*
 ---------------------------------------------------------------------------------------------------------------------
 This file should not be build! It contains the implementations of the ResourceManager class in resource_manager.h and
 is included there. Building this file will throw erros. Exclude it from build!
 ---------------------------------------------------------------------------------------------------------------------
*/

template <class T>
ResourceManager<T>::ResourceManager(std::string resource_file_path)
{
	m_resource_file_path = resource_file_path;
}

template <class T>
ResourceManager<T>::~ResourceManager()
{
}

template <class T>
bool ResourceManager<T>::GetResourcePathFromFile(std::string resource_id, std::string &path)
{
	// Open associated resource file
	std::ifstream resource_file;
	resource_file.open(m_resource_file_path);

	if (!resource_file.is_open())
	{
		LogManager::LogLine("Error: Could not open resource file (" + m_resource_file_path + ").");
		return false;
	}

	std::string buffer;
	bool resource_found = false;

	// Try to find the name of the resource.
	do
	{
		std::getline(resource_file, buffer);
		if (buffer == "#" + resource_id)
		{
			// If it was found, set the path.
			resource_found = true;
			std::getline(resource_file, path);
			break;
		}
	} while (!resource_file.eof());

	if (!resource_found)
	{
		LogManager::LogLine("Error: Could not find path to resource '" + resource_id + "'.");
		return false;
	}

	resource_file.close();
	return true;
}

template <class T>
T ResourceManager<T>::GetResource(std::string resource_id)
{
	std::unordered_map<std::string, T>::const_iterator element_iterator = m_resources.find(resource_id);
	
	// If the requested resource is not in the list...
	if (element_iterator == m_resources.end())
	{
		//...load it first.
		if(!LoadResource(resource_id))
		{
			LogManager::LogLine("Error: Could not load resource '" + resource_id + "'.");
			return NULL;
		}
	}

	// Return the resource
	return m_resources.at(resource_id);
}

template <class T>
bool ResourceManager<T>::FreeResource(std::string resource_id)
{
	std::unordered_map<std::string, T>::const_iterator element_iterator = m_resources.find(resource_id);
	
	// If the requested resource is not in the list... error!
	if (element_iterator == m_resources.end())
	{
		LogManager::LogLine("Error: Could not delete resource '" + resource_id + "' because this resource does not exist.");
		return false;
	}

	// Try to destroy the resource
	if (!DestroyResource(m_resources.at(resource_id)))
	{
		LogManager::LogLine("Error: Could not delete resource '" + resource_id + "'.");
		return false;
	}

	// If everything worked out: Delete the entry in the resource list
	m_resources.erase(element_iterator);
	return true;
}

template <class T>
bool ResourceManager<T>::FreeAllResources()
{
	while (!m_resources.empty())
	{
		if (!destroyResource(m_resources.begin()->first))
		{
			LogManager::LogLine("Error: Could not delete all resources because one resource could not be deleted.");
			return false;
		}
	}

	return true;
}